using System.Text.RegularExpressions;

namespace InfiniTec.DirectoryServices
{
	public static class PrincipalInfo
	{
		private static readonly Regex DistinguishedNameRegex = new Regex(@"
            ^(\w{2}\s?\={1}\s?\""?\b([\w\s]|(\\[\,\\=]))*?\b\""?)           # First token, ex: DC=Contoso
            ((\s?\,{1}\s?)                                                  # Comma after a token. Must be followed by another token
            (\w{2}\s?\={1}\s?\""?\b([\w\s]|(\\[\,\\=]))*?\b\""?)){0,}$      # All other tokens",
		                                                                 RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
		private static readonly Regex Nt4AccountNameRegex = new Regex(@"^\w*?\\\w*?$", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
		private static readonly Regex SidRegex = new Regex(@"^S-1-\d{1,3}(\-\d{1,}){1,}$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
		private static readonly Regex LegacyExchangeDnRegex = new Regex(@"^(\/O\s?\={1}\s?\""?\b([\w\s]|(\\[\,\\=]))*?\b\""?) ((\s?\/\s?) (\w{1,2}\s?\={1}\s?\""?\b([\w\s]|(\\[\,\\=]))*?\b\""?)){0,}$", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
		private static readonly Regex GuidRegex = new Regex(@"^\{?[a-fA-F\d]{8}-([a-fA-F\d]{4}-){3}[a-fA-F\d]{12}\}?$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
		private static readonly Regex EmailRegex = new Regex(@"^(?:(?#local-part)(?#quoted)""[^\""]*""|(?#non-quoted)[a-z0-9&+_-](?:\.?[a-z0-9&+_-]+)*)@(?:(?#domain)(?#domain-name)[a-z0-9](?:[a-z0-9-]*[a-z0-9])*(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])*)*|(?#ip)(\[)?(?:[01]?\d?\d|2[0-4]\d|25[0-5])(?:\.(?:[01]?\d?\d|2[0-4]\d|25[0-5])){3}(?(1)\]|))$", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);


		public static PrincipalNameType DeterminePrincipalNameType(string name)
		{
			if (GuidRegex.IsMatch(name))
			{
				return PrincipalNameType.Guid;
			}
			if (SidRegex.IsMatch(name))
			{
				return PrincipalNameType.SecurityIdentifier;
			}
			if (DistinguishedNameRegex.IsMatch(name))
			{
				return PrincipalNameType.DistinguishedName;
			}
			if (Nt4AccountNameRegex.IsMatch(name))
			{
				return PrincipalNameType.Nt4AccountName;
			}
			if (LegacyExchangeDnRegex.IsMatch(name))
			{
				return PrincipalNameType.LegacyExchangeDistinguishedName;
			}
			if (EmailRegex.IsMatch(name))
			{
				return PrincipalNameType.EmailAddress;
			}
			return PrincipalNameType.Unknown;
		}
	}
}